#include "gprs_task.h"
#include <etimer.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include "Mqtt_task.h"
#include "device_manage.h"
#include "disp_task.h"
#include "gsm.h"
#include "http_task.h"
#include "voice_task.h"
#include "net_api.h"
#include "time.h"
#include "tm1804.h"
#include "uart.h"

PROCESS(GprsInit_Process, "GprsInit");
PROCESS(GprsCMD_Process, "GprsCMD");
PROCESS(GprsRST_Process, "GprsRST");
PROCESS(Gprs_GetIPD_Process, "GprsRST");
PROCESS(Gprs_GetStatus_Process, "GprsGetStatus");

static bool is_gettime = false;  //时间是否获取标志
static bool is_play_nosim_flag = false;
static bool is_play_netfailed_flag = false;
static bool is_play_netsuccceed_flag = false;

extern uint8_t led;

void set_gprscmdval(sGprsCmd *GprsCmd, char *cmd, char *success_res,
                    char *failed_res, struct process *notify) {
  GprsCmd->cmd = (uint8_t *)cmd;
  GprsCmd->success_res = (uint8_t *)success_res;
  GprsCmd->failed_res = (uint8_t *)failed_res;
  GprsCmd->notify = notify;
}

PROCESS_THREAD(GprsCMD_Process, ev, data) {
  static uint16_t timeOut = 0;
  static uint8_t res = 0;
  static sGprsCmd GprsCmd;
  static struct etimer et;

  PROCESS_BEGIN();
  GprsCmd = *(sGprsCmd *)data;
  res = 0;
  timeOut = 10000;

  Gsm_ClearRecive();
  uart_send(GprsCmd.cmd, strlen((const char *)GprsCmd.cmd));
  etimer_set(&et, 50);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  
  while (timeOut--) {
    if (Gsm_WaitRecive() == GSM_REV_OK) {
      if (strstr((const char *)Net_IO.buf, (const char *)GprsCmd.success_res) !=
          NULL) {
        Gsm_ClearRecive();
        res = 1;
        break;
      } else if (strstr((const char *)Net_IO.buf,
                        (const char *)GprsCmd.failed_res) != NULL) {
        Gsm_ClearRecive();
        res = 2;
        break;
      }
    }

    etimer_set(&et, 2);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }
  if (GprsCmd.notify != NULL) {
    process_post(GprsCmd.notify, PROCESS_EVENT_CMDEND, (process_data_t)&res);
  }

  PROCESS_END();
}

PROCESS_THREAD(GprsInit_Process, ev, data) {
  static struct etimer et;
  static uint8_t step = 0;
  static uint8_t flag = 0;
  static uint8_t i = 0;
  static sGprsCmd cmd;
  static uint32_t tmp_time = 0;
  static uint8_t count = 0;
  static sVoiceCmd voice;
  static uint8_t voice_value;

  PROCESS_BEGIN();
  flag = 1;
  step = 0;

  etimer_set(&et, 100);
  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
  Gsm_ClearRecive();
  process_exit(&Gprs_GetIPD_Process);
  process_exit(&MqttLoop_Process);
  netstatus = net_idle;
  count = 0;
  Gsm_ATE(1);
  etimer_set(&et, 100);
  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
  led = Led_NoConnect;
  process_start(&DispLed_Process, (process_data_t)&led);
  printf("GprsInit_Process start \r\n");
  while (flag) {
    count++;
    if ((count / (step + 1)) >= 7) {
	  if(step == 0){
		printf("hvae not sim card  \r\n");
		if(!is_play_nosim_flag){
			is_play_nosim_flag = true;
			voice_value = voice_simcard;
			voice.cmd = voicecmd_playone;
			voice.value = (uint8_t *)&voice_value;
			process_start(&VoicePlay_Process, (process_data_t)&voice);
		}
	  }else{
		printf("gprs_netfailed \r\n");
		if(!is_play_netfailed_flag && !is_play_netsuccceed_flag){
			is_play_netfailed_flag = true;
			voice_value = voice_netfailed;
			voice.cmd = voicecmd_playone;
			voice.value = (uint8_t *)&voice_value;
			process_start(&VoicePlay_Process, (process_data_t)&voice);
		}
	  }
	  
	  printf("Gsm_ClearRecive  \r\n");
      gsm_rsthign();
      gsm_off();
      etimer_set(&et, 2500);
      PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
      gsm_rstlow();
      gsm_on();
      etimer_set(&et, 2500);
      PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
      count = 0;
      step = 0;
      uart_clear();
      Gsm_ClearRecive();
	  
      // HAL_NVIC_SystemReset();
      //      process_start(&GprsRST_Process, NULL);
      //      process_exit(&Gprs_GetIPD_Process);
      ////      return PT_ENDED;
    }
    if (step == 0) {  //检查卡
      i = 1;
      set_gprscmdval(&cmd, GSM_CPIN, GSM_CPIN_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 1000);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 0;
      }
      Gsm_ClearRecive();
    } else if (step == 1) {  //确认网络是否搜索成功
      i = 2;
      set_gprscmdval(&cmd, GSM_CERG, GSM_CERG_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 100);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 1;
      }
      Gsm_ClearRecive();
    } else if (step == 2) {  //确认网络是否搜索成功
      i = 1;
      set_gprscmdval(&cmd, GSM_CSQ, GSM_CSQ_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 100);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 2;
      }
      Gsm_ClearRecive();
    } else if (step == 3) {  //检查网络注册状态
      i = 2;
      set_gprscmdval(&cmd, GSM_CGREG, GSM_CGREG_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 100);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 3;
      }
      Gsm_ClearRecive();
    } else if (step == 4) {  //设置GPRS移动台模式为类别B
      i = 1;
      set_gprscmdval(&cmd, GSM_CGCLASS, GSM_CGCLASS_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 100);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 4;
      }
      Gsm_ClearRecive();
    } else if (step == 5) {  //查询是否已经附着GPRS
      i = 2;
      set_gprscmdval(&cmd, GSM_CHECKGATT, GSM_CHECKGATT_RES, GSM_CHECKGATT_ERES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step = 7;
      } else {
        step++;
      }
      Gsm_ClearRecive();
    } else if (step == 6) {  //附着GPRS
      i = 4;
      set_gprscmdval(&cmd, GSM_CGATT, GSM_CGATT_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 500);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 6;
      }
      Gsm_ClearRecive();
    } else if (step == 7) {  //设置PDP上下文
      i = 4;
      set_gprscmdval(&cmd, GSM_CGDCONT, GSM_CGDCONT_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
      } else {
        etimer_set(&et, 500);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 7;
      }
      Gsm_ClearRecive();
    } else if (step == 8) {  //激活PDP
      i = 2;
      set_gprscmdval(&cmd, GSM_CGACT, GSM_CGACT_RES, GSM_ERROE_RES,
                     &GprsInit_Process);
      gprssend_cmd(GprsCMD_Process, cmd, i);
      if (i > 0) {
        step++;
        etimer_set(&et, 500);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
      } else {
        etimer_set(&et, 2000);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        step = 0;
      }
      Gsm_ClearRecive();
    } else if (step == 9) {
      //			etimer_set(&et, 2000);
      //			PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
      //			process_start(&GprsRST_Process, NULL);
      //			process_exit(&GprsInit_Process);
      //			return PT_ENDED;

      if (is_gettime) {
        if (cfg_data.Val.DeviceFlag != Device_Init) {
          process_start(&HttpGetID_Process, (process_data_t)&GprsInit_Process);
          do {
            PROCESS_WAIT_EVENT();
          } while (ev != PROCESS_EVENT_CONTINUE);
          uint8_t res = *(uint8_t *)data;
          if (res == 1) {
            cfg_data.Val.DeviceFlag = Device_Init;
            write_cfg(&cfg_data);
          }
        } else {
          //启动mqtt
		  if(!is_play_netsuccceed_flag){
			  is_play_netsuccceed_flag = true;
			  voice_value = voice_netsuccess;
			  voice.cmd = voicecmd_playone;
			  voice.value = (uint8_t *)&voice_value;
			  process_start(&VoicePlay_Process, (process_data_t)&voice);
		  }
          led = Led_Connect;
          process_start(&DispLed_Process, (process_data_t)&led);
          Gsm_ATE(0);
          etimer_set(&et, 100);
          PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
          uart_clear();
          netstatus = net_idle;
          process_start(&MqttInit_Process, NULL);
          process_exit(&GprsInit_Process);
          return PT_ENDED;
        }
      } else {
        netstatus = net_idle;
        etimer_set(&et, 1000);
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        process_start(&HttpGetTime_Process, (process_data_t)&GprsInit_Process);
        tmp_time = HAL_GetTick();
        do {
          PROCESS_WAIT_EVENT();
        } while (ev != PROCESS_EVENT_CONTINUE &&
                 (HAL_GetTick() - tmp_time < 10000));
        static uint8_t res;
        res = *(uint8_t *)data;
        if (res == 1) {
          is_gettime = true;
        } else {
          step = 0;
          etimer_set(&et, 5000);
          PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
        }
      }
    }

    etimer_set(&et, 50);
    PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
  }
  PROCESS_END();
}

PROCESS_THREAD(GprsRST_Process, ev, data) {
  //	static sGprsCmd cmd;
  //	static uint8_t i = 0 ;
  static unsigned long last_time = 0;
  static unsigned long delay_time;
  static struct etimer et;


  PROCESS_BEGIN();
  process_exit(&Gprs_GetIPD_Process);
  process_exit(&MqttLoop_Process);
  process_exit(&Gprs_GetStatus_Process);
  Gsm_ClearRecive();
  //	flag = 0;
  //	i = 3;
  //	set_gprscmdval(&cmd, GSM_RST, GSM_RST_RES, GSM_ERROE_RES,
  //&GprsRST_Process); 	gprssend_cmd(GprsCMD_Process,cmd,i);
  gsm_rsthign();
  gsm_off();
  etimer_set(&et, 2500);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  gsm_rstlow();
  gsm_on();
  etimer_set(&et, 700);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  delay_time = 15000;
  last_time = HAL_GetTick();
  while ((HAL_GetTick() - last_time) < delay_time) {
    if (Gsm_WaitRecive() == GSM_REV_OK) {
      if (strstr((const char *)Net_IO.buf, GSM_START_RES) != NULL) {
        //				process_start(&GprsInit_Process, NULL);
        break;
      } else if (strstr((const char *)Net_IO.buf, GSM_CINIT_RES) != NULL) {
        delay_time += 6000;
      }
    }
    etimer_set(&et, 3);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  process_start(&GprsInit_Process, NULL);

  PROCESS_END();
}

PROCESS_THREAD(Gprs_GetIPD_Process, ev, data) {
  static uint16_t byte = 0;
  static uint16_t count = 0;
  static char sByte[5];
  static char *ptrIPD;
  static struct etimer et;
  static uint16_t index = 0;
  static uint8_t flag = 0;
  static uint16_t offset = 0;

  PROCESS_BEGIN();

  byte = 0;
  count = 0;

  while (1) {
    index = 0;
    if (Gsm_WaitRecive() == GSM_REV_OK) {  //如果接收完成
      while (1) {
        flag = 0;
        memset(sByte, 0, 5);
        ptrIPD =
            strstr((char *)&Net_IO.buf[index], "CIPRCV:");  //搜索“CIPRCV”头
        if (ptrIPD !=
            NULL) {  //如果没找到，可能是IPD头的延迟，还是需要等待一会，但不会超过设定的时间
          ptrIPD = strstr(ptrIPD, ":");
          ptrIPD++;  //找到':'  ，然后偏移到下一个字符，代表数据长度的第一个数字
          count = 0;
          while (*ptrIPD != ',') {  //在':'和',' 之间的都是数据长度的数据
            sByte[count++] = *ptrIPD++;
          }
          flag = 1;
          offset = ptrIPD - (char *)&Net_IO.buf[0];
        } else {
          Gsm_ClearRecive();
          break;
        }
        if (flag == 1) {
          byte = atoi(sByte);  //将字符转为数值形式
          ptrIPD++;  //此时ptrIPD指针还指向':'，所以需要偏移到下个数据
          if (byte > (fifo_get.Depth - fifo_get.Counter)) {
            byte = fifo_get.Depth - fifo_get.Counter;
          }
          FIFO_Add(&fifo_get, ptrIPD, byte);

          index = offset + 2 + byte;
        }
      }
    }
    etimer_set(&et, 3);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  PROCESS_END();
}

PROCESS_THREAD(Gprs_GetStatus_Process, ev, data) {
  static uint16_t timeOut = 0;
  static struct etimer et;
  static struct process *pro;
  static uint8_t res = 0;

  PROCESS_BEGIN();

  timeOut = 3000;
  gsm_info = Gsm_None;

  Gsm_ClearRecive();
  uart_send((uint8_t *)GSM_STATUS, strlen(GSM_STATUS));

  if (ev == PROCESS_EVENT_INIT) {
    pro = (struct process *)data;
  }
  res = 0;
  while (timeOut--) {  //等待
    if (Gsm_WaitRecive() == GSM_REV_OK) {
      if (strstr((const char *)Net_IO.buf, GSM_STATUS1_RES) != NULL) {
        gsm_info = Gsm_Conn;
        res = 1;
        break;
      } else if (strstr((const char *)Net_IO.buf, GSM_STATUS2_RES) != NULL) {
        gsm_info = Gsm_DisConn;
        res = 0;
        break;
      } else {
        res = 0;
        gsm_info = Gsm_DisConn;
      }
    }
    etimer_set(&et, 3);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  process_post(pro, PROCESS_EVENT_CONTINUE, &res);

  PROCESS_END();
}

void exit_gprs(void) {
  process_exit(&Gprs_GetStatus_Process);
  process_exit(&Gprs_GetIPD_Process);
  process_exit(&GprsInit_Process);
}
